package com.pulse.base.runner;

import com.alibaba.fastjson2.JSONObject;
import com.pulse.base.domain.CircuitMeasure;
import com.pulse.base.domain.CircuitMeasureRefer;
import com.pulse.base.service.ICircuitMeasureReferService;
import com.pulse.base.service.ICircuitMeasureService;
import com.pulse.common.core.redis.RedisCache;
import com.pulse.common.utils.DateUtils;
import com.pulse.mqtt.MqttConsumer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

import java.io.Console;
import java.util.Collection;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName JobRunner
 * @Description
 * @Author 陆帅
 * @Date 2024/9/4 11:59
 */
@Component
public class JobRunner implements CommandLineRunner {

    public static final Logger logger = LoggerFactory.getLogger(JobRunner.class);

    @Autowired
    private RedisCache redisCache;
    @Autowired
    private ICircuitMeasureReferService circuitMeasureReferService;
    @Autowired
    private ICircuitMeasureService circuitMeasureService;

    /**
     * @param args
     * @throws Exception
     */
    @Override
    public void run(String... args) throws Exception {
        new Thread(()->{
            while (true){
                try{
                    Collection<String> keys = redisCache.keys("jobQueue:*");
                    for(String key : keys){
                        String deviceNo = key.split(":")[1];
                        Object jobStatus = redisCache.getCacheObject("JobStatus:" + deviceNo);
                        if("1".equals(jobStatus)){ // 如果任务正在执行
                            continue;
                        }
                        String jobQueue = redisCache.pop(key);
                        if(jobQueue == null || jobQueue.isEmpty()){ // 如果消息队列中无数据
                            continue;
                        }

                        // 设置任务正在进行
                        redisCache.setCacheObject("JobStatus:"+deviceNo,"1",1, TimeUnit.MINUTES);
                        String[] s = jobQueue.split("_");
                        if(s.length!=4){
                            continue;
                        }
                        int channel = Integer.parseInt(s[1]);
                        int type = Integer.parseInt(s[2]);
                        long measureId = Long.parseLong(s[3]);
                        if(type == 2){ // 周期测试
                            CircuitMeasure circuitMeasure = new CircuitMeasure();
                            circuitMeasure.setType(2);
                            circuitMeasure.setDeviceNo(deviceNo);
                            circuitMeasure.setChannel(channel);
                            circuitMeasure.setDefaultMeasure(0);
                            circuitMeasure.setStatus(1);
                            circuitMeasure.setMeasureMode(1);
                            circuitMeasure.setCreateTime(DateUtils.getNowDate());

                            // 查找参考曲线
                            CircuitMeasureRefer circuitMeasureRefer = circuitMeasureReferService.selectCircuitMeasureReferByDeviceNoAndChannel(deviceNo, channel);
                            if(circuitMeasureRefer == null){
                                redisCache.setCacheObject("JobStatus:"+deviceNo,"0",1, TimeUnit.MINUTES);
                                circuitMeasure.setStatus(11);
                                circuitMeasure.setCircuitStatus(1);
                                circuitMeasure.setRemark("未设置参考曲线");
                                circuitMeasureService.insertCircuitMeasure(circuitMeasure);
                                continue;
                            }
                            CircuitMeasure refer = circuitMeasureService.selectCircuitMeasureByMeasureId(circuitMeasureRefer.getMeasureId());
                            if(refer == null){
                                redisCache.setCacheObject("JobStatus:"+deviceNo,"0",1, TimeUnit.MINUTES);
                                circuitMeasure.setStatus(11);
                                circuitMeasure.setCircuitStatus(1);
                                circuitMeasure.setRemark("未获取到参考曲线");
                                circuitMeasureService.insertCircuitMeasure(circuitMeasure);
                                continue;
                            }

                            circuitMeasure.setParamWaveLength(refer.getParamWaveLength());
                            circuitMeasure.setParamTestTime(refer.getParamTestTime());
                            circuitMeasure.setParamBackScatter(refer.getParamBackScatter());
                            circuitMeasure.setParamFinalThreshold(refer.getParamFinalThreshold());
                            circuitMeasure.setParamNonReflectThreshold(refer.getParamNonReflectThreshold());
                            circuitMeasure.setParamPw(refer.getParamPw());
                            circuitMeasure.setParamReflectThreshold(refer.getParamReflectThreshold());
                            circuitMeasure.setParamIor(refer.getParamIor());
                            circuitMeasure.setParamTestMode(refer.getParamTestMode());
                            circuitMeasure.setParamRd(refer.getParamRd());
                            circuitMeasureService.insertCircuitMeasure(circuitMeasure);

                            circuitMeasure.setFrom("scada_server1");

                            redisCache.setCacheObject("CircuitMeasureBack:"+deviceNo+"_"+channel,circuitMeasure,10, TimeUnit.MINUTES);
                            redisCache.push("MeasureTestList",deviceNo+"_"+channel+":"+circuitMeasure.getMeasureId().toString());

                            publishTest(circuitMeasure);
                        }
                        else if(type == 1){  // 点名测试
                            CircuitMeasure circuitMeasure = (CircuitMeasure)redisCache.getCacheObject("CircuitMeasure:" + deviceNo + "_" + channel + "_1"+"_"+measureId);
                            redisCache.setCacheObject("CircuitMeasureBack:"+deviceNo+"_"+channel,circuitMeasure,10,TimeUnit.MINUTES);
                            redisCache.push("MeasureTestList",deviceNo+"_"+channel+":"+circuitMeasure.getMeasureId().toString());
                            publishTest(circuitMeasure);
                        }
                        else if(type == 3){  // 复测

                        }
                    }
                }
                catch (Exception e){
                    try{
                        Thread.sleep(1000);
                    }
                    catch (InterruptedException ex){
                        ex.printStackTrace();
                    }
                }
            }
        }).start();
    }

    private void publishTest(CircuitMeasure circuitMeasure){
        try
        {
            JSONObject measureData = new JSONObject();
            measureData.put("cmd","start_otdr_measure");
            measureData.put("from",circuitMeasure.getFrom());
            measureData.put("moduleId","");
            measureData.put("to",circuitMeasure.getDeviceNo());
            measureData.put("uniId",1);

            JSONObject paramObj = new JSONObject();
            paramObj.put("IOR",Double.parseDouble(circuitMeasure.getParamIor()));
            paramObj.put("back_scatter",Double.parseDouble(circuitMeasure.getParamBackScatter()));
            paramObj.put("final_threashold",Double.parseDouble(circuitMeasure.getParamFinalThreshold()));
            paramObj.put("non_reflect_threashold",Double.parseDouble(circuitMeasure.getParamNonReflectThreshold()));
            paramObj.put("plus_width",circuitMeasure.getParamPw());
            paramObj.put("range_dist",circuitMeasure.getParamRd());
            paramObj.put("reflect_threashold",Double.parseDouble(circuitMeasure.getParamReflectThreshold()));
            paramObj.put("test_mode",circuitMeasure.getParamTestMode());
            paramObj.put("test_time",circuitMeasure.getParamTestTime());
            paramObj.put("wave_length",circuitMeasure.getParamWaveLength());
            paramObj.put("osw_port_id",circuitMeasure.getChannel());

            measureData.put("param",paramObj);

            // 发送开始采集命令 start_otdr_measure
            String msg = measureData.toJSONString();
            MqttConsumer.publish("$FAMS/OTU/"+circuitMeasure.getDeviceNo()+"/ctrl-down",msg);
        }
        catch (Exception e)
        {
            logger.error("发布测试错误：",e);
        }
    }
}
